// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SnapObjects.Data.AspNetCore
{
    internal static class DataReader
    {
        private static readonly IDictionary<DataFormat, IList<string>> contentTypes;

        static DataReader()
        {
            contentTypes = new Dictionary<DataFormat, IList<string>>();

            var jsonTypes = new List<string>()
            {
                "application/json",
                "application/json-patch+json"
            };

            contentTypes.Add(DataFormat.Json, jsonTypes);

            var xmlTypes = new List<string>()
            {
                "application/xml",
                "text/xml"
            };

            contentTypes.Add(DataFormat.Xml, xmlTypes);
        }

        public static DataFormat? ReadDataFromatFromContentType(string contentType)
        {
            foreach (var v in contentTypes)
            {
                foreach (var t in v.Value)
                {
                    if (contentType.ToLower().Contains(t))
                    {
                        return v.Key;
                    }
                }
            }

            return null;
        }

        public static async Task<string> ReadContentAsStringAsync(
            Stream content, string contentType, CancellationToken cancellationToken)
        {
            using (var memory = new MemoryStream())
            {
                var bytes = new byte[1024];
                int count;

                while ((count = await content.ReadAsync(
                    bytes, 0, 1024, cancellationToken)) > 0)
                { 
                    memory.Write(bytes, 0, count);
                }

                var encoding = GetEncoding(contentType);

                return encoding.GetString(memory.ToArray());
            }
        }

        private static Encoding GetEncoding(string contentType)
        {
            var charsetName = String.Empty;

            if (!String.IsNullOrEmpty(contentType))
            {
                var temp = contentType.Split(';');

                if (temp.Length > 1)
                {
                    var charset = temp[temp.Length - 1];

                    var index = charset.IndexOf("=");

                    if (index > 0)
                    {
                        charsetName = charset.Substring(index + 1).Trim();
                    }
                }
            }

            if (!String.IsNullOrEmpty(charsetName))
            {
                var encoding = Encoding.GetEncoding(charsetName);

                if (encoding != null)
                {
                    return encoding;
                }
            }

            return Encoding.UTF8;
        }
    }
}
